package com.qingxin.sys.service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.RandomStringUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;

import com.qingxin.sys.dao.Querier;
import com.qingxin.sys.dao.Updater;
import com.qingxin.sys.entity.WxUser;
import com.qingxin.sys.mvc.PageParam;
import com.qingxin.sys.mvc.Pager;
import com.qingxin.sys.mvc.SysError;
import com.qingxin.sys.support.UploadFile;
import com.qingxin.sys.utils.BeanUtil;
import com.qingxin.sys.utils.DateUtil;
import com.qingxin.sys.utils.StringUtils;

@Service
public class WxUserService extends BaseService<WxUser, String> {

	
	
	/**
	 * 生成账号名
	 * @return
	 */
	public String createNickname(){
		String nickname = "u"+RandomStringUtils.random(8, "0123456789");
		WxUser wxUser = getByProperty("nickname", nickname);
		while(wxUser != null){
			nickname = "u"+RandomStringUtils.random(8, "0123456789");
			wxUser = getByProperty("nickname", nickname);
		}
		return nickname;
	}
	
	
	/**
	 * 创建唯一身份标识，用于在网络上传播的用户身份标识
	 * @return
	 */
	public String createTokenid(){
		//年月日以36进制形式各占一位
		DateTime dateTime = new DateTime();
		int year = ((dateTime.getYear() + 1) % 100) % Character.MAX_RADIX;
		if(year >= Character.MAX_RADIX){
			year = 0;
		}
		String tag = Integer.toString(year, Character.MAX_RADIX)
				+ Integer.toString(dateTime.getMonthOfYear(), Character.MAX_RADIX)
				+ Integer.toString(dateTime.getDayOfMonth(), Character.MAX_RADIX);
		
		String tokenid = RandomStringUtils.random(13, "0123456789abcdefghijklmnopqrstuvwxyz") + tag;
		WxUser wxUser = getByProperty("tokenid", tokenid);
		while(wxUser != null){
			tokenid = RandomStringUtils.random(13, "0123456789abcdefghijklmnopqrstuvwxyz") + tag;
			wxUser = getByProperty("tokenid", tokenid);
		}
		return tokenid;
	}
	
	
	/**
	 * 通过唯一身份标识获取用户信息
	 * @param phone
	 * @return
	 */
	public WxUser getWxUserByTokenid(String tokenid){
		if(StringUtils.isEmpty(tokenid)){
			return null;
		}
		return getByProperty("tokenid", tokenid);
	}
	
	/**
	 * 通过手机号获取用户信息
	 * @param phone
	 * @return
	 */
	public WxUser getWxUserByPhone(String phone){
		if(StringUtils.isEmpty(phone)){
			return null;
		}
		return getByProperty("phone", phone);
	}
	
	
	/**
	 * 通过微信号获取用户信息
	 * @param wechat
	 * @return
	 */
	public WxUser getWxUserByWechat(String wechat){
		if(StringUtils.isEmpty(wechat)){
			return null;
		}
		return getByProperty("wechat", wechat);
	}
	
	
	/**
	 * 通过登录用户名或手机号获取会员用户信息
	 * @return
	 */
	public WxUser getWxUserByLoginNameOrPhone(String name){
		if(StringUtils.isEmpty(name)){
			return null;
		}
		WxUser wxUser = (WxUser) getByHql("from WxUser where loginName=? or phone=?", name, name);
		return wxUser;
	}
	
	
	
	/**
	 * 列表数据
	 * @param search
	 * @param pageParam
	 * @param request
	 * @return
	 */
	public Pager list(String search, PageParam pageParam, HttpServletRequest request){
		Querier querier = Querier.create("from WxUser u where 1=1 ");
		
		if(StringUtils.isNotEmpty(search)){
			search = "%"+search.replace("'", "")+"%";
			querier.append(" and (u.phone like :phone or u.username like :username or u.nickname like :nickname)");
			querier.setParam("phone", search);
			querier.setParam("username", search);
			querier.setParam("nickname", search);
		}
		
		querier.append(pageParam.getOrderby(" order by u.createTime desc"));
		
		Pager pager = pageByQuerier(querier, pageParam);
		return pager;
	}
	
	
	public SysError add(WxUser wxUser, HttpServletRequest request){
		WxUser user = getByProperty("loginName", wxUser.getLoginName());
		if(user != null){
			return new SysError("用户名已存在");
		}
		user = getWxUserByPhone(wxUser.getPhone());
		if(user != null){
			return new SysError("手机号已存在");
		}
		
		wxUser.setPasswd(StringUtils.md5(wxUser.getPasswd()));
		
		wxUser.setWechat("");
		wxUser.setPhoto("");
		
		wxUser.setCreateTime(new Date());
		wxUser.setLoginModified(1);
		wxUser.setTokenid(createTokenid());
		
		this.save(wxUser);
		return null;
	}
	
	
	/**
	 * 更新
	 * @param wxUser
	 * @param request
	 * @return
	 */
	public SysError update(WxUser wxUser, HttpServletRequest request){
		WxUser old = getSafeEntity(wxUser.getWxuserid());
		if(old == null){
			return new SysError("用户信息不存在");
		}
		
		if(isPhoneDuplicate(wxUser.getPhone(), wxUser.getWxuserid())){
			return new SysError("phone", "该手机号已存在");
		}
		
		String fields = "phone,username,nickname,regionid,address,sex,birth,remark";
		BeanUtil.setTargetFields(old, wxUser, fields, true);
		
		Updater<WxUser> updater = new Updater<>(old, fields);
		this.update(updater);
		
		return null;
	}
	
	
	/**
	 * 重置密码
	 * @param wxuserid
	 * @param resetPasswd
	 * @param request
	 * @return
	 */
	public Object resetPassword(String wxuserid, String resetPasswd, HttpServletRequest request){
		WxUser old = getSafeEntity(wxuserid);
		if(old == null){
			return new SysError("用户信息不存在");
		}
		if(StringUtils.isEmpty(resetPasswd) || resetPasswd.length()<6){
			resetPasswd = "12345678";
		}
		
		old.setPasswd(StringUtils.md5(resetPasswd));
		
		Updater<WxUser> updater = new Updater<>(old, "passwd");
		this.update(updater);
		
		Map<String, String> map = new HashMap<String, String>();
		map.put("newpwd", resetPasswd);
		return map;
	}
	
	
	/**
	 * APP注册
	 * @param loginName
	 * @param phone
	 * @param loginPwd
	 * @param request
	 * @return
	 */
	public SysError addReg(String loginName, String phone, String loginPwd, String code, HttpServletRequest request){
		if(loginName.length()<3){
			return new SysError("账号名最少3位");
		}
		if(loginName.length()>20){
			return new SysError("账号名最多20位");
		}
		if(!loginName.matches("[0-9a-zA-Z]{3,20}")){
			return new SysError("账号名只能由字母和数字组成");
		}
		if(loginPwd.length()<6){
			return new SysError("密码长度最少6位");
		}
		if(loginPwd.length()>20){
			return new SysError("密码长度最多20位");
		}
		
		WxUser user = getByProperty("loginName", loginName);
		if(user != null){
			return new SysError("用户名已存在");
		}
		user = getWxUserByPhone(phone);
		if(user != null){
			return new SysError("手机号已存在");
		}
		user = new WxUser();
		user.setLoginName(loginName);
		user.setPhone(phone);
		user.setPasswd(StringUtils.md5(loginPwd));
		
		user.setWechat("");
		user.setUsername("");
		user.setNickname(createNickname());
		user.setRegionid("");
		user.setAddress("");
		user.setCreateTime(new Date());
		user.setPhoto("");
		user.setLoginModified(1);
		user.setTokenid(createTokenid());
		user.setSex("");
		//user.setBirth(null);
		user.setRemark("");
		
		this.save(user);
		
		return null;
	}
	
	
	/**
	 * 通过微信登录创建新账号
	 * @param wxid
	 * @param request
	 * @return
	 */
	public SysError addByWx(String wxid, HttpServletRequest request){
		WxUser user = getWxUserByWechat(wxid);
		if(user != null){
			return new SysError("该微信已绑定用户");
		}
		
		user = new WxUser();
		//user.setLoginName(null);
		//user.setPhone(null);
		//user.setPasswd(null);
		
		user.setWechat(wxid);
		user.setUsername("");
		user.setNickname(createNickname());
		user.setRegionid("");
		user.setAddress("");
		user.setCreateTime(new Date());
		user.setPhoto("");
		user.setLoginModified(0);
		user.setTokenid(createTokenid());
		user.setSex("");
		//user.setBirth(null);
		user.setRemark("");
		
		this.save(user);
		
		return null;
	}
	
	
	/**
	 * 绑定微信
	 * @param wxuserid
	 * @param wxid
	 * @return
	 */
	public SysError updateWxOpenid(String wxuserid, String wxid){
		WxUser user = getSafeEntity(wxuserid);
		if(user == null){
			return new SysError("用户信息不存在");
		}
		user.setWechat(wxid);
		
		Updater<WxUser> updater = new Updater<>(user, "wechat");
		this.update(updater);
		return null;
	}
	
	
	/**
	 * 通过微信新建账号后完善用户信息
	 * @param wxuserid
	 * @param loginName
	 * @param phone
	 * @param loginPwd
	 * @param request
	 * @return
	 */
	public SysError updateWxReg(String wxuserid, String loginName, String phone, String loginPwd, HttpServletRequest request){
		if(loginName.length()<3){
			return new SysError("账号名最少3位");
		}
		if(loginName.length()>20){
			return new SysError("账号名最多20位");
		}
		if(!loginName.matches("[0-9a-zA-Z]{3,20}")){
			return new SysError("账号名只能由字母和数字组成");
		}
		if(loginPwd.length()<6){
			return new SysError("密码长度最少6位");
		}
		if(loginPwd.length()>20){
			return new SysError("密码长度最多20位");
		}
		
		WxUser old = getSafeEntity(wxuserid);
		if(old == null){
			return new SysError("用户信息不存在");
		}
		
		WxUser user = getByProperty("loginName", loginName);
		if(user != null){
			return new SysError("用户名已存在");
		}
		user = getWxUserByPhone(phone);
		if(user != null){
			return new SysError("手机号已存在");
		}
		
		old.setLoginName(loginName);
		old.setPasswd(StringUtils.md5(loginPwd));
		old.setPhone(phone);
		old.setLoginModified(1);
		
		Updater<WxUser> updater = new Updater<>(old, "loginName,passwd,phone,loginModified");
		this.update(updater);
		
		return null;
	}
	
	
	/**
	 * 更新头像
	 * @param wxuserid
	 * @param photo
	 * @return
	 */
	public SysError updateUserPhoto(String wxuserid, String photo){
		WxUser user = getSafeEntity(wxuserid);
		if(user == null){
			return new SysError("用户信息不存在");
		}
		if(StringUtils.isNotEmpty(photo)){
			UploadFile.moveTmpTo(photo, UploadFile.DIR_USER_PHOTO);
		}
		user.setPhoto(photo);
		Updater<WxUser> updater = new Updater<>(user, "photo");
		this.update(updater);
		return null;
	}
	
	
	
	/**
	 * 更新手机号
	 * @param wxuserid
	 * @param phone
	 * @return
	 */
	public SysError updateUserPhone(String wxuserid, String phone){
		WxUser user = getSafeEntity(wxuserid);
		if(user == null){
			return new SysError("用户信息不存在");
		}
		user.setPhone(phone);
		Updater<WxUser> updater = new Updater<>(user, "phone");
		this.update(updater);
		return null;
	}
	
	
	
	/**
	 * 修改密码
	 * @param wxuserid
	 * @param loginPwd
	 * @return
	 */
	public SysError updateLoginPwd(String wxuserid, String loginPwd){
		WxUser wxUser = getSafeEntity(wxuserid);
		if(wxUser == null){
			return new SysError("用户不存在");
		}
		if(StringUtils.isEmpty(loginPwd)){
			return new SysError("密码不能为空");
		}
		if(loginPwd.length()<6){
			return new SysError("密码长度最少6位");
		}
		if(loginPwd.length()>20){
			return new SysError("密码长度最多20位");
		}
		
		loginPwd = StringUtils.md5(loginPwd);
		wxUser.setPasswd(loginPwd);
		
		Updater<WxUser> updater = new Updater<>(wxUser, "passwd");
		this.update(updater);
		return null;
	}
	
	
	
	/**
	 * 修改身份标识tokenid
	 * @param wxuserid
	 * @return
	 */
	public SysError updateTokenid(String wxuserid){
		WxUser wxUser = getSafeEntity(wxuserid);
		if(wxUser == null){
			return new SysError("用户不存在");
		}
		String tokenid = createTokenid();
		wxUser.setTokenid(tokenid);
		
		Updater<WxUser> updater = new Updater<>(wxUser, "tokenid");
		this.update(updater);
		return null;
	}
	
	
	/**
	 * 删除用户信息
	 * @param wxuserids
	 * @param request
	 * @return
	 */
	public SysError delete(String[] wxuserids, HttpServletRequest request){
		for(String wxuserid : wxuserids){
			WxUser user = getSafeEntity(wxuserid);
			if(user == null){
				continue;
			}
			
			this.delete(user);
		}
		return null;
	}
	
	
	/**
	 * 完善个人信息
	 * @param wxid
	 * @param username
	 * @param nickname
	 * @param regionid
	 * @param address
	 * @param sex
	 * @param birth
	 * @param request
	 * @return
	 */
	public SysError updateWxUserinfo(String wxid, String username, String nickname, String regionid,
			String address, String sex, String birth, String remark, HttpServletRequest request){
		WxUser wxUser = getWxUserByWechat(wxid);
		if(wxUser == null){
			return new SysError("用户信息不存在");
		}
		
		Date birthday = null;
		if(StringUtils.isNotEmpty(birth) && !"undefined".equalsIgnoreCase(birth)){
			birthday = DateUtil.parse(birth, "yyyy-MM-dd");
		}
		
		wxUser.setUsername("undefined".equals(username) ? "" : username);
		wxUser.setNickname("undefined".equals(nickname) ? "" : nickname);
		wxUser.setRegionid("undefined".equals(regionid) ? "" : regionid);
		wxUser.setAddress("undefined".equals(address) ? "" : address);
		wxUser.setSex("undefined".equals(sex) ? "" : sex);
		wxUser.setBirth(birthday);
		wxUser.setRemark("undefined".equals(remark) ? "" : remark);
		
		Updater<WxUser> updater = new Updater<>(wxUser, "username,regionid,address,sex,birth,remark");
		this.update(updater);
		return null;
		
	}
	
	
	/**
	 * 判断手机号是否重复
	 * @param phone
	 * @param wxuserid
	 * @return
	 */
	public boolean isPhoneDuplicate(String phone, String wxuserid){
		if(StringUtils.isEmpty(wxuserid)){
			Object val = getByHql("select wxuserid from WxUser where phone=?", phone);
			return val!=null;
		}else{
			Object val = getByHql("select wxuserid from WxUser where phone=? and wxuserid<>?", phone, wxuserid);
			return val!=null;
		}
	}
	
	
}
